package Ejercicio2;

import java.io.Serializable;
import java.rmi.MarshalledObject;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.activation.Activatable;
import java.rmi.activation.ActivationDesc;
import java.rmi.activation.ActivationGroup;
import java.rmi.activation.ActivationGroupDesc;
import java.rmi.activation.ActivationGroupID;
import java.rmi.activation.ActivationID;
import java.rmi.registry.LocateRegistry;
import java.util.Properties;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;



public class ServidorChat extends Activatable implements Servidor, Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private CopyOnWriteArrayList<Cliente> clientes;
	private AtomicLong numMensaje; 
	Executor pool;
	private int contador = 1;
	
	public ServidorChat(ActivationID id, MarshalledObject<ServidorChat> marshallObject) throws RemoteException {
		super(id, 0);
		clientes = new CopyOnWriteArrayList<Cliente>();
		numMensaje = new AtomicLong();
		pool = Executors.newFixedThreadPool(20);
	}
	
	@Override
	public void difundir(final String mensaje) throws RemoteException {
		final long n = numMensaje.getAndIncrement();
		for (final Cliente c : clientes) {
			pool.execute(new Runnable() {
				
				@Override
				public void run() {
					try {
						c.recibir(n + ": " + mensaje);
					} catch (RemoteException e) {
						e.printStackTrace();
					}
					
				}
			});
		}
	}
	
	
	@Override
	public int inscribirse(Cliente c) throws RemoteException {
		clientes.add(c);
		return contador++;
	}
	
	public static void main(String[] args) throws Exception {
		String policy =
			    System.getProperty("examples.activation.policy", "group.policy");
			String implCodebase =
			    System.getProperty("examples.activation.impl.codebase");
			String filename =
			    System.getProperty("examples.activation.file", "");

			Properties props = new Properties();
			props.put("java.security.policy", policy);
			props.put("java.class.path", "no_classpath");
			props.put("examples.activation.impl.codebase", implCodebase);
			if (filename != null && !filename.equals("")) {
			    props.put("examples.activation.file", filename);
			    
			}

			ActivationGroupDesc groupDesc = new ActivationGroupDesc(props, null);
			
			ActivationGroupID groupID = 
				    ActivationGroup.getSystem().registerGroup(groupDesc);
			
			MarshalledObject<String> data = null;
			//if (filename != null && !filename.equals("")) {
			   data = new MarshalledObject<String>(null);
			//}

			ActivationDesc desc =
			    new ActivationDesc(groupID, ServidorChat.class.getName(), implCodebase, data);
			
			Remote stub = Activatable.register(desc);
			
			String name = System.getProperty("examples.activation.name");
			LocateRegistry.getRegistry().rebind(name, stub);
			
			
			System.out.println("Server ready");
	}
}
